﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Caching;
using System.Web.Mvc;
using Gueei.Gallery.Core.Entities;
using Gueei.Gallery.Core.Filters;
using Gueei.Gallery.Core.Repositories;
using Gueei.Gallery.Core.Services;
using Gueei.Gallery.Core.ViewModels;
using Gueei.Gallery.Security;
using Gueei.Gallery.Web.Exceptions;
using Gueei.Gallery.Web.RequestModels;
using Gueei.Gallery.Web.ViewModels;

namespace Gueei.Gallery.Web.Controllers
{
	public class ImageController : Controller
	{
		private readonly IImageService _imageService;
		private readonly IDisplayProfileRepository _displayRepo;

		public const int MaxFileSizeAllowed = 471859200; // 450MB

		public ImageController(IImageService imageService, IDisplayProfileRepository displayRepo)
		{
			_imageService = imageService;
			_displayRepo = displayRepo;
		}

		[HttpGet]
		public ActionResult New()
		{
			return View(new NewImageViewModel());
		}

		[HttpPost]
		public ActionResult New(NewImageViewModel newImage, HttpPostedFileBase imageFile)
		{
			if (ModelState.IsValid)
			{
				if (imageFile != null)
				{
					// workaround.  IE report jpeg as pjpeg
					var contentType = imageFile.ContentType == "image/pjpeg" ? "image/jpeg" : imageFile.ContentType;
					if (Image.IsImageType(contentType))
					{
						var data = new byte[imageFile.ContentLength];
						imageFile.InputStream.Read(data, 0, imageFile.ContentLength);
						var img = _imageService.SaveNewImage
							(newImage.Tags, newImage.Name, String.Empty, imageFile.FileName, contentType, null, data);
						return View(img);
					}
					else
					{
						ModelState.AddModelError("imageFile", "File supplied is not an image file");
					}
				}
				else
				{
					ModelState.AddModelError("imageFile", "File is required");
				}
			}
			return View(newImage);
		}

		[HttpGet]
		[OutputCache(Duration=2000, VaryByParam="*")]
		public FileContentResult Get(GetImageModel query)
		{
			Response.AddCacheItemDependency("images!");
			/*
			var cache = HttpContext.Cache["Gueei.Gallery.Image.Get" + query.Id];
			if ((cache!=null) && (cache is FileContentResult))
			{
				return (FileContentResult)cache;
			}
			*/
			var profile = query.Profile == null
							? _displayRepo.DefaultDisplayProfile
							: _displayRepo.GetDisplayProfileByName(query.Profile);

			if (!_imageService.ImageExists(query.Id))
				throw new ResourceNotFoundException("Image with id: " + query.Id.ToString() + " is not exists.");
			var image = _imageService.GetImage(query.Id);
			var imageFile = _imageService.GetImageFile(query.Id, profile);
			/*
			HttpContext.Cache.Add("Gueei.Gallery.Image.Get" + query.Id,
			                      new FileContentResult(imageFile, image.MimeType),
			                      null, Cache.NoAbsoluteExpiration,
			                      TimeSpan.FromSeconds(200),
			                      CacheItemPriority.Normal,
			                      null
				);
			*/
			return new FileContentResult(imageFile, image.MimeType);
		}
		/*
				[HttpPost]
				public ActionResult BatchUpload(BatchUploadViewModel model, HttpPostedFileBase compressedFile)
				{
					if (ModelState.IsValid)
					{
						// Test if can check content length before upload
						if (compressedFile.ContentLength>MaxFileSizeAllowed)
						{
							ModelState.AddModelError("compressedFile", "Uploaded file cannot larger than " + MaxFileSizeAllowed / 1048576 + " MB. ");
							return View(model);
						}
						using (var filecompress = new FileCompressionService(Settings.Settings.TempDirectory))
						{
							var data = new byte[compressedFile.ContentLength];
							compressedFile.InputStream.Read(data, 0, compressedFile.ContentLength);
							var decompressedFiles = filecompress.DecompressFiles(data);
							var counter = 1;
							foreach (var f in decompressedFiles)
							{
								var imageName = model.BatchName + "(" + counter + ")";

								// Ignore non-image files
								if (!Image.FileExtensionIsImageType(f.Extension)) continue;
								_imageService.SaveNewImage(model.Tags, imageName, f.Name, String.Empty,
														   Image.GetMimeTypeFromFileExtension(f.Extension),
														   null,
														   f
									);
								counter++;
							}

							return RedirectToAction("Index", "Browse");
						}
					}
					else
					{
						return View(model);
					}
				}
		*/
		[AuthorizeToEdit]
		public ActionResult View(Guid id, bool editMode=false)
		{
			Image image;
			if (id.Equals(Guid.Empty) || ((image = _imageService.GetImage(id)) == null))
				throw new ResourceNotFoundException("Image with id: " + id.ToString() + " is not exists.");
			if (editMode) return View("Edit", ImageEditViewModel.CreateFromImage(image));
			return View(ImageEditViewModel.CreateFromImage(image));
		}

		[HttpGet]
		public ActionResult Edit(Guid id)
		{
			Image image;
			if (id.Equals(Guid.Empty) || ((image = _imageService.GetImage(id)) == null))
				throw new ResourceNotFoundException("Image with id: " + id.ToString() + " is not exists.");

			return View(ImageEditViewModel.CreateFromImage(image));
		}

		
	}
}
